﻿using EFCore.BulkExtensions;
using Furion;
using Furion.DatabaseAccessor;
using Furion.DynamicApiController;
using Furion.FriendlyException;
using Furion.UnifyResult;
using JoyAdmin.Core;
using Mapster;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Serilog;
using StackExchange.Profiling.Internal;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using TulingMember.Application.Dto;
using TulingMember.Core; 
using Yitter.IdGenerator;

namespace TulingMember.Application
{
    [ApiDescriptionSettings("销售退货单")]
    public class SaleOrderBackService : IDynamicApiController
    {
        private readonly ILogger _logger; 
        private readonly IRepository<cts_Customer> _customerRepository;
        private readonly IRepository<cts_CustomerPayLog> _customerpaylogRepository;
        private readonly IRepository<cts_SaleOrderBack> _saleorderRepository;
        private readonly IRepository<cts_SaleOrderDetailBack> _saleorderdetailRepository;
        private readonly IRepository<cts_PrintTag> _printtagRepository;
        private readonly IRepository<cts_Product> _productRepository;
        private readonly IRepository<cts_ProductLog> _productlogRepository;
        public SaleOrderBackService(ILogger logger
            , IRepository<cts_Customer> customerRepository
            , IRepository<cts_CustomerPayLog> customerpaylogRepository
            , IRepository<cts_SaleOrderBack> saleorderRepository
            , IRepository<cts_SaleOrderDetailBack> saleorderdetailRepository
            , IRepository<cts_PrintTag> printtagRepository
            , IRepository<cts_Product> productRepository
            , IRepository<cts_ProductLog> productlogRepository)
        {
            _logger = logger;
            _customerRepository = customerRepository;
            _customerpaylogRepository = customerpaylogRepository;
            _saleorderRepository = saleorderRepository;
            _saleorderdetailRepository = saleorderdetailRepository;
            _printtagRepository = printtagRepository;
            _productRepository = productRepository;
            _productlogRepository = productlogRepository;
        }


        #region 退货单
        /// <summary>
        /// 列表
        /// </summary> 
        public PagedList<cts_SaleOrderBack> SearchSaleOrderBack(BaseInput input)
        {

            var search = _saleorderRepository.AsQueryable();
            if (!string.IsNullOrEmpty(input.keyword))
            {
                search = search.Where(m => m.CustomerName.Contains(input.keyword)
                 || m.OrderDesc.Contains(input.keyword));
            }
            if (input.sdate != null)
            {
                search = search.Where(m => m.CreatedTime >= input.sdate);
            }
            if (input.edate != null)
            {
                var edate = input.edate?.AddDays(1).Date;
                search = search.Where(m => m.CreatedTime < edate);
            }
            if (input.customerid > 0)
            {

                search = search.Where(m => m.CustomerId == input.customerid);
            }
            var amount = search.GroupBy(m => 1).Select(m => new
            {
                Amount = m.Sum(m => m.Amount),
                FreightFee = m.Sum(m => m.FreightFee),
                EditionFee = m.Sum(m => m.EditionFee),
                GiveupFee = m.Sum(m => m.GiveupFee),
                AllFee = m.Sum(m => m.AllFee),
                PayFee = m.Sum(m => m.PayFee)
            }).FirstOrDefault();
            search = search.OrderByDescending(m => m.OrderDate).OrderByDescending(m => m.OrderNo);
            var data = search.ToPagedList(input.page, input.size);
            UnifyContext.Fill(amount);
            return data;
        }
        /// <summary>
        /// 获取退货单
        /// </summary> 

        public SaleOrderBackDto GetSaleOrderBack(long id)
        {

            var order = _saleorderRepository.FindOrDefault(id);
            var detail = _saleorderdetailRepository.Where(m => m.OrderId == id).ToList();
            var printtag = _printtagRepository.Where(m => m.IsShow == 1).ToList();
            return new SaleOrderBackDto
            {
                printtag = printtag,
                order = order,
                detail = detail
            };
        }
        /// <summary>
        /// 获取退货单打印
        /// </summary> 

        public SaleOrderBackDto GetSaleOrderBackAndPrint(long id)
        {

            var order = _saleorderRepository.FindOrDefault(id);
            var detail = _saleorderdetailRepository.Where(m => m.OrderId == id).ToList();
            var printtag = _printtagRepository.Where(m => m.IsShow == 1).ToList();
            //获取系统配置
            var tenantid = App.User.FindFirst(ClaimConst.TENANT_ID).Value;
            cts_SystemConfig systemconfig = new cts_SystemConfig();
            var configKey = AppStr.SystemConfig + "_" + tenantid;
            var systemconfigStr = RedisHelper.GetString(configKey);
            if (!string.IsNullOrEmpty(systemconfigStr))
            {
                systemconfig = systemconfigStr.FromJson<cts_SystemConfig>();
            }
            order.PrintNum += 1;
            return new SaleOrderBackDto
            {
                companyname= systemconfig.configstr1,
                printtag = printtag,
                order = order,
                detail = detail
            };
        }
        /// <summary>
        /// 保存退货单
        /// </summary>
        /// <param name="dto"></param>
        /// <returns></returns>
        [SecurityDefine("saleorderback")]
        [UnitOfWork]
        public long SaveSaleOrderBack(SaleOrderBackDto dto)
        {
            var order = dto.order;
            var detail = dto.detail;
            if (detail.GroupBy(g => g.ProductId).Where(s => s.Count() > 1).Count() > 0)
            {
                throw Oops.Bah("商品重复，请检查").StatusCode(ErrorStatus.ValidationFaild);
            }

            var today = DateTime.Now.ToString("yyyyMMdd");
            var tenantid = App.User.FindFirst(ClaimConst.TENANT_ID).Value;

            //获取系统配置
            cts_SystemConfig systemconfig = new cts_SystemConfig();
            var configKey = AppStr.SystemConfig + "_" + tenantid;
            var systemconfigStr = RedisHelper.GetString(configKey);
            if (!string.IsNullOrEmpty(systemconfigStr))
            {
                systemconfig = systemconfigStr.FromJson<cts_SystemConfig>();
            }

            order.Num = detail.Sum(m => m.Num);
            order.Weight = Math.Round(detail.Sum(m => Math.Round(m.Weight, 2, MidpointRounding.AwayFromZero)), 2, MidpointRounding.AwayFromZero);
            if (systemconfig.config4 == 1)//保留整数
            {
                order.Amount = detail.Sum(m => Math.Floor(m.Price * m.Num));
                order.AllFee = Math.Floor(order.Amount + order.FreightFee + order.EditionFee - order.GiveupFee);

            }
            else
            {
                order.Amount = Math.Round(detail.Sum(m => Math.Round(m.Price * m.Num, 2, MidpointRounding.AwayFromZero)), 2, MidpointRounding.AwayFromZero);
                order.AllFee = Math.Round(order.Amount + order.FreightFee + order.EditionFee - order.GiveupFee, 2, MidpointRounding.AwayFromZero);

            }
            order.OrderDesc = string.Join(';', detail.Select(m => m.ProductName));

            if (order.Id == 0)
            {  
                var redisKey = AppStr.SaleOrderBackNoKey + "_" + tenantid + "_" + today;
                var OrderNoIndex = RedisHelper.StringIncrement(redisKey);
                if (OrderNoIndex == 0)
                {
                    OrderNoIndex = RedisHelper.StringIncrement(redisKey);
                }
                order.Id = YitIdHelper.NextId();
                order.OrderNo = "TH" + today + OrderNoIndex.ToString().PadLeft(3, '0');
                order.Status = 0;
                _saleorderRepository.Insert(order);

                foreach (var item in detail)
                {
                    var productName = item.ProductName.Trim(); 
                    item.OrderId = order.Id;
                    item.Id = YitIdHelper.NextId(); 
                    if (systemconfig.config4 == 1)//保留整数
                    {
                        item.Amount = Math.Floor(item.Price * item.Num);
                    }
                    else
                    {
                        item.Amount = Math.Round(item.Price * item.Num, 2, MidpointRounding.AwayFromZero);
                    }
                    _saleorderdetailRepository.Insert(item); 


                } 
            }
            else
            {
                         
                var oldOrder = _saleorderRepository.DetachedEntities.Where(m => m.Id == order.Id).FirstOrDefault();
                if (oldOrder.Status ==1)
                {
                    throw Oops.Bah("已审核退货单不允许修改").StatusCode(ErrorStatus.ValidationFaild);
                }
                _saleorderRepository.UpdateExclude(order,new string[] {nameof(order.PrintNum) });
                _saleorderdetailRepository.Where(a => a.OrderId ==order.Id).BatchDelete();
                foreach (var item in detail)
                {
                    var productName = item.ProductName.Trim();
                    item.OrderId = order.Id;
                    item.Id = YitIdHelper.NextId();
                    if (systemconfig.config4 == 1)//保留整数
                    {
                        item.Amount = Math.Floor(item.Price * item.Num);
                    }
                    else
                    {
                        item.Amount = Math.Round(item.Price * item.Num, 2, MidpointRounding.AwayFromZero);
                    }
                    _saleorderdetailRepository.Insert(item);
                     
                }
            }
            return order.Id;

        }
        /// <summary>
        /// 删除 
        /// </summary>  
        [SecurityDefine("saleorderback")]
        public void DeleteSaleOrderBack(long id)
        {

            var oldOrder = _saleorderRepository.DetachedEntities.Where(m => m.Id == id).FirstOrDefault();
            if (oldOrder.Status == 1)
            {
                throw Oops.Bah("已审核退货单不允许删除").StatusCode(ErrorStatus.ValidationFaild);
            }
            _saleorderRepository.FakeDelete(id);
        }
        /// <summary>
        /// 审核、弃审 
        /// </summary>  
        [SecurityDefine("saleorderback")]
        [UnitOfWork]
        public void CheckSaleOrderBack(CheckDto input)
        {

            var order = _saleorderRepository.FindOrDefault(input.Id);
            if (order.Status == input.Status)
            {
                throw Oops.Bah("该单据无需此操作").StatusCode(ErrorStatus.ValidationFaild);
            }
            order.Status=input.Status; 
            var orderDetails=_saleorderdetailRepository.Where(m=>m.OrderId==order.Id).ToList();
           

            var changeAmount = Math.Round(order.AllFee - order.PayFee, 2, MidpointRounding.AwayFromZero);
            if (input.Status == 1)//审核
            {
                //1.变更客户金额
                var customer = _customerRepository.FindOrDefault(order.CustomerId);   
                _customerpaylogRepository.Insert(
                    new cts_CustomerPayLog
                    {
                        CustomerId= customer.Id,
                        CustomerName=customer.Name,
                        OrderType = OrderType.Out,
                        OrderId=order.Id,
                        OrderNo=order.OrderNo,
                        OldAmount = customer.Balance,
                        ChangeAmount=changeAmount,
                        NewAmount= customer.Balance + changeAmount,
                        OrderDate=order.OrderDate, 
                        Remark=$"【退货单】费用：{order.AllFee}元,实退：{order.PayFee}元",
                    });
                customer.Balance += changeAmount;
                //3.库存数量变更
                foreach (var item in orderDetails)
                {
                    var product = _productRepository.FindOrDefault(item.ProductId);
                   
                    _productlogRepository.Insert(new cts_ProductLog
                    {
                        Id=YitIdHelper.NextId(),    
                        ProductId = product.Id,
                        ProductName = product.Name,
                        OldNum = product.Num,
                        ChangeNum = item.Num,
                        NewNum = product.Num + item.Num,
                        TagName = "退货单入库",
                        TagType = ProductChangeTag.In,
                        RelationId =order.Id, 
                    });
                    product.Num += item.Num;
                }

            }
            else
            { //弃审
              //1.变更客户金额
                var customer = _customerRepository.FindOrDefault(order.CustomerId); 
                _customerpaylogRepository.Insert(
                    new cts_CustomerPayLog
                    {
                        CustomerId = customer.Id,
                        CustomerName = customer.Name,
                        OrderType = OrderType.Out,
                        OrderId = order.Id,
                        OrderNo = order.OrderNo,
                        OldAmount = customer.Balance,
                        ChangeAmount = -changeAmount,
                        NewAmount = customer.Balance - changeAmount,
                        OrderDate = order.OrderDate,
                        Remark = "退货单弃审",
                    });
                customer.Balance -= changeAmount;
                //3.库存数量变更
                foreach (var item in orderDetails)
                {
                    var product = _productRepository.FindOrDefault(item.ProductId);

                    _productlogRepository.Insert(new cts_ProductLog
                    {
                        Id = YitIdHelper.NextId(),
                        ProductId = product.Id,
                        ProductName = product.Name,
                        OldNum = product.Num,
                        ChangeNum = -item.Num,
                        NewNum = product.Num - item.Num,
                        TagName = "退货单入库弃审",
                        TagType = ProductChangeTag.Out,
                        RelationId = order.Id,
                    });
                    product.Num -= item.Num;
                }
            } 
        }
        #endregion



    }
}
